home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The X-Philes (2nd Revision)
/
The X-Philes Number 1 (1995).iso
/
xphiles
/
hp48_2
/
mach.cod
< prev
next >
Wrap
Text File
|
1991-04-12
|
11KB
|
257 lines
Article 1500 of comp.sys.handhelds:
Path: en.ecn.purdue.edu!pur-ee!mentor.cc.purdue.edu!purdue!bu.edu!snorkelwacker!bloom-beacon!bloom-beacon!athena.mit.edu!chekmate
From: chekmate@athena.mit.edu (Adam Kao)
Newsgroups: comp.sys.handhelds
Subject: routines to enter HP48 machine language programs
Message-ID: <1990Mar14.183918.15326@athena.mit.edu>
Date: 14 Mar 90 18:39:18 GMT
Sender: news@athena.mit.edu (News system)
Reply-To: chekmate@athena.mit.edu (Adam Kao)
Organization: Massachusetts Institute of Technology
Lines: 242
=====================================================================
NOTE1: This is being posted for me by a friend, since I have no usenet
or email access right now. If you want to respond to something
in this article, you'll have to use (gasp) regular mail. Hurry
up while it's still $.25.
NOTE2: All of the SYSEVAL addresses contained in these routines are
valid for the HP48SX Version A only.
In a previous article, Alonzo Gariepy posted information on using the
memory scanning utility built into the HP48 to enter machine language
programs. The three routines below provide a similar capability, without
having to use the memory scanner. They are adapted from routines that
I have been using on the HP28S. The main routine, STR->OBJ, takes a string
of hex digits and returns the object whose representation is those digits.
This can be used to create just about anything you want, including
machine language routines. Some examples are shown below.
I have provided a little documentation on the SYSEVALs used, but I am
assuming some familiarity with how HP28/HP48 objects are represented,
and with the machine code of the Saturn CPU.
Dave Kaffine
33 Agassiz Ave.
Belmont, MA 02178
(617) 484-3393
==================================================================
RVRS [2022h] 75.5 bytes ; Reverses the characters in a string
<< -> s
<< "" ; Start with empty string on stack
s SIZE 1 FOR x ; Loop from end to beginning
s x x SUB + ; and add each character
-1 STEP
>>
>>
SYSRCL [6E80h] 54 bytes
; Given an address (as a binary integer),
; puts the object at that address
; on the stack without evaluating it.
; Can also be used with other data types - see
; detailed description below.
; NOTE: For the most part, this should not be
; dangerous until you try to do something
; with the recalled item.
<< #4003h SYSEVAL ; <2h> (short integer - prolog 02911)
#56B6h SYSEVAL ; described below
DROP ; DROPs boolean value
>>
The routine at 056B6 works as follows:
2: COMP ==> 2: Object or
1: <Nh> 1: TRUE 1: FALSE
The routine ignores the type of the object in level 2. It assumes that
COMP consists of a series of objects, one after another (e.g. a list).
Each list object either consists of a known prolog and the associated data for
that object type, or is a 5-nibble address that is assumed to point to
some data object. The routine locates the Nth object and puts it on the
stack as follows: If the Nth object in the list starts with a prolog, a
pointer to the object within the list is put on the stack. If the Nth
object in the list is an address pointing to an actual object, that address
is copied to the stack. If N is out of range, a FALSE value is put on the
stack, otherwise a TRUE value is put on the stack (FALSE and TRUE are
special objects used by internal routines. They are displayed as
"External").
Some notes: This routine works well with lists, but since the prolog of
the level 2 object is not checked, it gives interesting results with other
data types. For example, with a binary integer argument:
Binary integer <-- Increasing addresses
MSB-------------LSB length prolog (ignored)
b bbbbb bbbbb aaaaa 00015 02A4E <-- Level 2
\ \
\ \-- 1st object
\
\-- 2nd object (interpreted as an address
unless aaaaa = known prolog)
So, if the level one argument has the value 2 (as in the SYSRCL routine),
and the level 2 argument is # aaaaah, the address aaaaa will be put on the
stack, which is the same as RCLing the object located at address aaaaa.
(BTW, #18CEAh SYSEVAL converts a real number to a short integer type, and
#18DBFh SYSEVAL converts the other way)
Example using SYSRCL:
#1AB67h SYSRCL ==> +
STR->OBJ [C2h] 169 bytes
; STRing to OBJect : This takes a string that is
; the sequence of nibbles that represent an object
; you want to create, and translates it into
; a new string that, when stored in memory,
; contains a nibble sequence that matches the digits
; in the original string. It then uses SYSRCL
; (see explanation of how that works above,
; and see additional notes below) to bring the
; desired object to the stack.
<< RCLF SWAP 64 STWS
-> s
<< "" ; Start with empty string
1 s SIZE FOR x ; Loop through string by pairs of
"#" ; characters
s x DUP 1 + SUB ; Get pair of digits (single digit
RVRS ; at end handled correctly)
+ "h" + OBJ-> ; Swap order, make binary integer
B->R CHR + ; make into character and append
2 STEP ; Loop by 2
>>
'obj' STO ; Store result so it won't move
obj SYSRCL ; RCL desired object to stack
NEWOB ; Make it a private copy
SWAP STOF ; Clean up
>>
More notes about the routine at 056B6:
This time we're calling it with a "string" as the composite type.
Let's assume the string starts at address sssss.
String (constructed to look like a program)
5th char 1st
| | length String prolog
... xx xx xx xx xx xx 23 61 E0 2D 9D LLLLL 02A2C : sssss
\ \
\ \-- Object 1
\
\-- Object 2 - starts with 02D9D,
the prolog for a program, so
object consists of entire
program.
SYSRCL will RCL the program by placing the address (sssss+10) on the
stack. Unfortunately, this address is not a 'good' address, since it
doesn't point to a 'real' object, it points inside of an object that is not
normally considered a composite type. This means that if the string gets
moved (e.g. as a result of garbage collection), the address on the stack
will NOT be updated properly!! That is the reason STR->P stores the
string in the global variable obj first (it must be a global variable - local
variables do not make copies of their contents) so its position won't be
affected by garbage collection. After calling SYSRCL, NEWOB is used to
make a separate copy of the item on the stack, so that the string it was
derived from can be deleted safely. Note that this program does not depend
upon being in the HOME directory - it does create one global variable called
'obj', but it doesn't matter where in memory 'obj' gets stored.
Here are some examples of the above routines in use:
Start with a simple, relatively safe example:
Keystrokes Results
-------------------------------------------------------
"D9D20E163276BA193632B2130" ==> "..."
DUP BYTES ==> #A0BDh 30
DROP2 ==> "..."
STR->OBJ ==> << + >>
Try it out - see if it's real.
3 5 ROT ==> 3 5 << + >>
EVAL ==> 8
!!!
Now for a more complicated example:
PEEK [A1BCh] 50 bytes
1: # aaaaah ==> 1: # ddddddddddddddddh
dddddddddddddddd is 16 nibbles of data from address aaaaa.
The least significant nibble of data is from address aaaaa,
the most significant is from aaaaa + F.
D9D20 ; Begin program
E1632 ; <<
BB691 ; B->R - make sure arg is binary integer,
B9691 ; R->B - and force new storage for it.
CCD20 ; In-line code prolog
03000 ; 48 nibbles (includes these 5 nibbles)
147 C=DAT1 A ; C -> level 1 object
137 CD1EX ; D1 -> level 1 object,
06 RSTK=C ; save old D1 on stack
179 D1=D1+ 10 ; D1 -> data of lvl 1 binary integer
147 C=DAT1 A ; C = 5 nibs from binary (addr to PEEK)
137 CD1EX ; D1 = PEEK addr, C -> lvl 1 data area
15BF A=DAT1 16 ; peek 16 nibs into A
137 CD1EX ; D1 -> lvl 1 data area
159F DAT1=A 16 ; Replace binary data with peeked data
07 C=RSTK ; Get old D1
137 CD1EX ; and restore
142 A=DAT0 A ; End every
164 D0=D0+ 5 ; routine
808C PC=(A) ; this way.
93632 ; >>
B2130 ; End program
To enter this, do the following:
"D9D20E1632BB691B ; Direct copy of sequence of
9691CCD200300014 ; nibbles above (NOTE: Do not
7137061791471371 ; put any extra characters in -
5BF137159F071371 ; there are no spaces or newline
42164808C93632B2 ; characters)
130"
DUP BYTES ; ==> #1412h, 88
DROP2
STR->OBJ ; ==> << B->R R->B Code >>
'PEEK' STO ;
'PEEK' BYTES ; ==> #A1BCh, 50
Now test it out:
#0 PEEK ==> # 8001FDAD801B9632h
That's all for now. Enjoy!